package com.blue.Impl.workflow;

import com.blue.common.constant.CommonConstant;
import com.blue.vo.workflow.TaskInstanceVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.blue.mapper.workflow.TaskInstanceMapper;
import com.blue.po.workflow.TaskInstancePO;
import com.blue.service.workflow.ITaskInstanceService;
import org.springframework.util.CollectionUtils;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service
public class TaskInstanceServiceImpl extends ServiceImpl<TaskInstanceMapper, TaskInstancePO> implements ITaskInstanceService {

    @Override
    public void computeTime(String status, List<TaskInstancePO> taskInstancePOS) {
        if (CollectionUtils.isEmpty(taskInstancePOS)) {
            return;
        }
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        //待处理的需要计算距离当前已滞留时长
        if (CommonConstant.PENDING.equals(status)) {
            LocalDateTime end = LocalDateTime.now();
            taskInstancePOS.forEach(item -> {
                String createTime = item.getCreateTime();
                LocalDateTime start = LocalDateTime.parse(createTime, dateTimeFormatter);
                Duration duration = Duration.between(start, end);
                long hours = duration.toHours();//相差的小时数
                long minutes = duration.toMinutes() % 60;//相差的分钟数
                item.setRetentionTime((hours == 0 ? "" : hours + "小时") + minutes + "分钟");
            });
            //非待处理计算节点耗时
        } else {
            taskInstancePOS.forEach(item -> {
                LocalDateTime start = LocalDateTime.parse(item.getCreateTime(), dateTimeFormatter);
                LocalDateTime end = LocalDateTime.parse(item.getOperationTime(), dateTimeFormatter);
                Duration duration = Duration.between(start, end);
                long hours = duration.toHours();//相差的小时数
                long minutes = duration.toMinutes() % 60;//相差的分钟数
                item.setRetentionTime((hours == 0 ? "" : hours + "小时") + minutes + "分钟");
            });
        }
    }

    @Override
    public List<TaskInstanceVO> taskNodeList(String instanceId) {
        List<TaskInstanceVO> taskInstanceVOS = baseMapper.taskNodeList(instanceId);
        Map<String, List<TaskInstanceVO>> map = taskInstanceVOS.stream()
                .peek(x -> {
                    if (StringUtils.isNotBlank(x.getRelateTaskId())) {
                        String relateAssignee = taskInstanceVOS.stream()
                                .filter(y -> x.getRelateTaskId().equals(y.getId()))
                                .map(TaskInstanceVO::getAssignee)
                                .findFirst()
                                .orElse(null);
                        x.setRelateAssignee(relateAssignee);
                    }
                })
                .sorted((data1, data2) -> data2.getCreateTime().compareTo(data1.getCreateTime()))
                .collect(Collectors.groupingBy(data -> data.getSort() + data.getCurrentNodeId()));
        List<TaskInstanceVO> list = new ArrayList<>();
        map.forEach((key, value) -> {
            if (value.size() == 1) {
                list.add(value.get(0));
            } else if (value.size() > 1) {
                TaskInstanceVO taskInstanceVO = new TaskInstanceVO();
                TaskInstanceVO taskInstance = value.get(0);
                String multiType = taskInstance.getMultiType();
                taskInstanceVO.setAssignee(CommonConstant.OR_SIGN.equals(multiType) ? "或签(只需一名审批人同意或拒绝即可)" : "会签(需要所有审批人同意，不限顺序)");
                taskInstanceVO.setSort(taskInstance.getSort());
                taskInstanceVO.setChildren(value);
                list.add(taskInstanceVO);
            }
        });
        list.sort((data1, data2) -> data2.getSort().compareTo(data1.getSort()));
        return list;
    }
}
